/**
 *@class VCM Vanchu Mobile JavaScript library
 *@author Anderlu
 *@param 
 */
var VCM = {};
VCM.version = "0.1";
/**
 *@author Anderlu
 *@param args:
 */

VCM.doAjax = function(args){

};
/**
 *@author Anderlu
 *@arguments args: {object}
 *@param id: VCM.uuid(), // dialog id
 *@param type:"custom",// 弹层类型 （custom、alert、confirm）
 *@param html:null,// html类型弹层的内容
 *@param title: null, // alert 与 confirm 的弹层标题
 *@param message: null,//  alert 与 confirm 的弹层内容
 *@param cancelText: null, // 取消按钮文本
 *@param cancelCallback: null,//取消的回调函数
 *@param cancelClass: null,//取消按钮的样式类
 *@param doneText: null,//确定按钮文本
 *@param doneCallback: null,//确定的回调函数
 *@param doneClass: null,//确定按钮的样式类
 *@param onShow: null, //弹层显示后回调
 *@param onBeforeShow:null,//弹层显示前回调
 *@param onHide:null,//弹层关闭后回调
 *@param onBeforeHide:null,//弹层关闭前回调
 *@param mask: true, //是否有底层遮罩
 *@param timeOut: 0,//延时自动关闭，单位毫秒
 *@param container: "#wrap",
 *@param offset:{left:0,top:0}
 *@description 采用jQ插件与自实现的方式
 */
VCM.dialog = function(args){
};/**
 *@author Anderlu
 *@arguments args: {object}
 *@param id: VCM.uuid(), // dialog id
 *@param message: null,//  
 *@param onShow: null, //弹层显示后回调
 *@param onBeforeShow:null,//弹层显示前回调
 *@param onHide:null,//弹层关闭后回调
 *@param onBeforeHide:null,//弹层关闭前回调
 *@param timeOut: 0,//延时自动关闭，单位毫秒
 *@param container: "#wrap",
 *@param offset:{left:0,top:0}
 *@description 
 */
VCM.tips = function(args){
};
/**
 *@author Anderlu
 *@param 
 *@description 刷新布局
 */
VCM.refreshView = function(){
	
}
/**
 *@author Anderlu
 *@param 
 *@description 隐藏浏览器地址栏
 */
VCM.hideAddressBar = function(){
/*	
	if (jq.os.desktop)
	    return jQUi.css("height", "100%");
	if (jq.os.android) {
	    window.scrollTo(1, 1);
	    if (document.documentElement.scrollHeight < window.outerHeight / window.devicePixelRatio)
	        jQUi.css("height", (window.outerHeight / window.devicePixelRatio) + 'px');
	} 
	else {
	    document.documentElement.style.height = "5000px";
	    
	    window.scrollTo(0, 1);
	    document.documentElement.style.height = window.innerHeight + "px";
	    jQUi.css("height", window.innerHeight + "px");
	}
*/
}
/**
 *@author Anderlu
 *@param content : {el}
 *@param options :{object}
 *@example	{
 *			scrollingX : true ,
 *			scrollingY : true ,
 *			animating : true ,
 *			bouncing : true ,
 *			locking : true ,
 *			paging : false ,
 *			snapping : false ,
 *			zooming : false ,
 *			minZoom : 0.5 ,
 *			maxZoom : 3
 *		}
 *@description touch device Scroller simulator
 */
VCM.scroller = function(content, options) {
};
/**
 *@author Anderlu
 *@param searchClass,node,tag
 */
VCM.getElementsByClass = function (searchClass,node,tag) {
    var classElements = new Array();
    if ( node == null ){	
   		node = document;
	}	
    if ( tag == null ){
    	tag = '*';
    }
    var els = node.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
    for (var i = 0, j = 0; i < elsLen; i++) {
        if ( pattern.test(els[i].className) ) {
            classElements[j] = els[i];
            j++;
        }
    }
    return classElements;
}
/**
 *@author Anderlu
 *@param 
 */
VCM.getViewport = function(){
	//屏幕分辨率的宽
	window.screen.width;
	//屏幕分辨率的高
	window.screen.height
};
/**
 *@author Anderlu
 *@param 
 */
VCM.browser = {}
/**
 *@author Anderlu
 *@param 
 */
VCM.os = {};
/**
 * Utility function to create a psuedo GUID
 * var id= $.uuid();
 *@author Anderlu
 *@param 
 */
VCM.uuid = function () {
    var S4 = function () {
        return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
    }
    return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
};
/**
 *@author Anderlu
 *@param 
 */
VCM.debug = function(){
	if (window.console && window.console.log){  
		console.log(arguments);
		//console.info(arguments);
		//console.dir(arguments);
	}
};

(function(){
	
	/**
	 *@author Anderlu
	 *@param 
	 *@description initialization browser detect
	 */
	var prefix = (function(args){
			var docStyle = document.documentElement.style,
				engine;
			if (window.opera && Object.prototype.toString.call(opera) === "[object Opera]") {
				engine = "presto";
			} else if ("MozAppearance" in docStyle) {
				engine = "gecko";
			} else if ("WebkitAppearance" in docStyle) {
				engine = "webkit";
			} else if (typeof navigator.cpuClass === "string") {
				engine = "trident";
			}
			var prefix = {
				trident: "ms",
				gecko: "Moz",
				webkit: "Webkit",
				presto: "O"
			}[engine];
			return prefix;
	})();
	VCM.browser.msie = "ms" === prefix ? true : false;
	VCM.browser.safari = VCM.browser.Chrome = "Webkit" === prefix ? true : false;
	VCM.browser.opera = "O" === prefix  ? true : false;
	VCM.browser.mozilla = VCM.browser.moz = "Moz" === prefix ? true : false;
	/**
	 *@author Anderlu
	 *@param 
	 *@description initialization operation system detect
	 */	
	var userAgent = navigator.userAgent;
	VCM.os.webkit = userAgent.match(/WebKit\/([\d.]+)/) ? true : false;
	VCM.os.opera = userAgent.match(/Opera Mobi/) ? true : false;
	VCM.os.android = userAgent.match(/(Android)\s+([\d.]+)/) || userAgent.match(/Silk-Accelerated/) ? true : false;
	VCM.os.ipad = userAgent.match(/(iPad).*OS\s([\d_]+)/) ? true : false;
	VCM.os.iphone = !VCM.os.ipad && userAgent.match(/(iPhone\sOS)\s([\d_]+)/) ? true : false;
	VCM.os.webos = userAgent.match(/(webOS|hpwOS)[\s\/]([\d.]+)/) ? true : false;
	VCM.os.touchpad = VCM.os.webos && userAgent.match(/TouchPad/) ? true : false;
	VCM.os.ios = VCM.os.ipad || VCM.os.iphone;
	VCM.os.blackberry = userAgent.match(/BlackBerry/) || userAgent.match(/PlayBook/) ? true : false;
	VCM.os.fennec = userAgent.match(/fennec/i) ? true : false;
	VCM.os.desktop = !(VCM.os.ios || VCM.os.android || VCM.os.blackberry || VCM.os.opera || VCM.os.fennec);
	
	/**
	 *@author Anderlu
	 *@param 
	 *@description initialization Scroller com component
	 */
	var scroller = function(content, options) {
		this.initialize(content, options);
	};
	scroller.prototype = {
		initialize : function(content, options){
			this.content = content;
			this.container = content.parentNode;
			this.options = options || {};
			//init horizontal
			if(options.scrollingY == false){
				var childWidth = parseInt(window.getComputedStyle(content.children[0],"").width);
				content.style.width = childWidth * content.children.length + "px";
			}
			// create Scroller instance
			var that = this;
			if(Scroller){
				this.scroller = new Scroller(function(left, top, zoom) {
					that.render(left, top, zoom);
				}, options);
			} else {
				VCM.debug("Scroller is undefined!");
				return false;
			}
			// bind events
			this.bindEvents();
			
			// the content element needs a correct transform origin for zooming
			this.content.style[VCM.scroller.vendorPrefix + 'TransformOrigin'] = "left top";
			
			// reflow for the first time
			this.reflow();
		},
		render :  (function() {
			var docStyle = document.documentElement.style,
				engine;
			if (window.opera && Object.prototype.toString.call(opera) === '[object Opera]') {
				engine = 'presto';
			} else if ('MozAppearance' in docStyle) {
				engine = 'gecko';
			} else if ('WebkitAppearance' in docStyle) {
				engine = 'webkit';
			} else if (typeof navigator.cpuClass === 'string') {
				engine = 'trident';
			}
			
			var vendorPrefix = VCM.scroller.vendorPrefix = {
				trident: 'ms',
				gecko: 'Moz',
				webkit: 'Webkit',
				presto: 'O'
			}[engine],
			helperElem = document.createElement("div"),
			undef,
			perspectiveProperty = vendorPrefix + "Perspective",
			transformProperty = vendorPrefix + "Transform";
			
			if (helperElem.style[perspectiveProperty] !== undef) {
				
				return function(left, top, zoom) {
					this.content.style[transformProperty] = 'translate3d(' + (-left) + 'px,' + (-top) + 'px,0) scale(' + zoom + ')';
				};	
				
			} else if (helperElem.style[transformProperty] !== undef) {
				
				return function(left, top, zoom) {
					this.content.style[transformProperty] = 'translate(' + (-left) + 'px,' + (-top) + 'px) scale(' + zoom + ')';
				};
				
			} else {
				
				return function(left, top, zoom) {
					this.content.style.marginLeft = left ? (-left/zoom) + 'px' : '';
					this.content.style.marginTop = top ? (-top/zoom) + 'px' : '';
					this.content.style.zoom = zoom || '';
				};
				
			}
		})(),
		bindEvents : function(){
			var that = this;
			// reflow handling
			window.addEventListener("resize", function() {
				that.reflow();
			}, false);
			// touch devices bind touch events
			if ('ontouchstart' in window) {
				this.container.addEventListener("touchstart", function(e) {
					// Don't react if initial down happens on a form element
					if (e.touches[0] && e.touches[0].target && e.touches[0].target.tagName.match(/input|textarea|select/i)) {
						return;
					}
					that.scroller.doTouchStart(e.touches, e.timeStamp);
					e.preventDefault();
				}, false);
		
				document.addEventListener("touchmove", function(e) {
					that.scroller.doTouchMove(e.touches, e.timeStamp, e.scale);
				}, false);
		
				document.addEventListener("touchend", function(e) {
					that.scroller.doTouchEnd(e.timeStamp);
				}, false);
		
				document.addEventListener("touchcancel", function(e) {
					that.scroller.doTouchEnd(e.timeStamp);
				}, false);
			// non-touch bind mouse events
			} else {
				var mousedown = false;
				this.container.addEventListener("mousedown", function(e) {
					if (e.target.tagName.match(/input|textarea|select/i)) {
						return;
					}
					that.scroller.doTouchStart([{
						pageX: e.pageX,
						pageY: e.pageY
					}], e.timeStamp);
					mousedown = true;
					e.preventDefault();
				}, false);
				
				document.addEventListener("mousemove", function(e) {
					if (!mousedown) {
						return;
					}
					that.scroller.doTouchMove([{
						pageX: e.pageX,
						pageY: e.pageY
					}], e.timeStamp);
					mousedown = true;
				}, false);
					
				document.addEventListener("mouseup", function(e) {
					if (!mousedown) {
						return;
					}
					that.scroller.doTouchEnd(e.timeStamp);
					mousedown = false;
				}, false);
		
				this.container.addEventListener("mousewheel", function(e) {
					if(that.options.zooming) {
						that.scroller.doMouseZoom(e.wheelDelta, e.timeStamp, e.pageX, e.pageY);	
						e.preventDefault();
					}
				}, false);	
			}
		},
		reflow : function(){
			// set the right scroller dimensions
			this.scroller.setDimensions(this.container.clientWidth, this.container.clientHeight, this.content.offsetWidth, this.content.offsetHeight);
			// refresh the position for zooming purposes
			//var rect = this.container.getBoundingClientRect();
			//this.scroller.setPosition(rect.left + this.container.clientLeft, rect.top + this.container.clientTop);
		}
	};
	VCM.scroller = function(content, options) {
	    return new scroller(content, options);
	};
	
	/**
	 *@author Anderlu
	 *@param 
	 *@description initialization dialog component
	 */	
	var dialog = function(opts) {
		this.initialize(opts);
	};
    dialog.prototype = {
    	opts : {},
		isShow: false,
        initialize : function(opts){
        	this.opts = $.extend({
				id: VCM.uuid(), // dialog id
				type:"custom",// 弹层类型 （custom、alert、confirm）
				html:null,// html类型弹层的内容
		        title: null, // alert 与 confirm 的弹层标题
		        message: null,//  alert 与 confirm 的弹层内容
		        cancelText: null, // 取消按钮文本
		        cancelCallback: null,//取消的回调函数
		        cancelClass: null,//取消按钮的样式类
		        doneText: null,//确定按钮文本
		        doneCallback: null,//确定的回调函数
		        doneClass: null,//确定按钮的样式类
		        onShow: null, //弹层显示后回调
		        onBeforeShow:null,//弹层显示前回调
		        onHide:null,//弹层关闭后回调
		        onBeforeHide:null,//弹层关闭前回调
		        mask: true, //是否有底层遮罩
		        timeOut: 0,//延时自动关闭，单位毫秒
		        container: "#wrap",
		        offset:{
					left:0,
					top:0
				}
        	}, opts);
        	VCM.debug("dialog initialize ",this.opts,opts);
        	this[this.opts.type]();
		},
		custom : function (){
			VCM.debug("custom dialog",this.opts);
			var that = this,
				opts = this.opts,
				//assemble html
				markup = (function(){
					if( typeof opts.html == "string"){
						return "<div id=\""+ opts.id +"\" class=\"ui_dialog hidden\">"+ opts.html +"</div>";
					}else{
						return $("<div id=\""+ opts.id +"\" class=\"ui_dialog hidden\"></div>").html(opts.html);
					}
				})();
			//show dialog
			that.show(markup);
		},
		alert : function (){
			VCM.debug("alert dialog",this.opts);
			var that = this,
				opts = this.opts,
				//assemble html
				markup = "<div id=\""+ opts.id +"\" class=\"ui_dialog hidden\">"+ opts.title +"<br/>"+ opts.message +"</div>";
			//show dialog
			that.show(markup);
		},
		confirm : function(){
			VCM.debug("confirm dialog",this.opts);
			var that = this,
				opts = this.opts,
				//assemble html
				markup = "<div id=\""+ opts.id +"\" class=\"ui_dialog hidden\">"+ opts.title +"<br/>"+ opts.message +"<br/>"+ opts.doneText +"<br/>"+ opts.cancelText +"</div>";
			//show dialog
			that.show(markup);
		},
        show : function(markup) {
			var that = this,
				opts = this.opts,
				container = $(opts.container); 
			if(VCM.dialog.indexOf(VCM.dialog.queue,opts.id) == -1){//VCM.dialog.queue.indexOf(that)
				// new dialog 
	            container.append(markup);
	            that.target =  $("#"+opts.id);
	            // show mask or not
	            opts.mask && that.showMask(container,opts);
	            //set center position
	            that.setPosition(container,that.target);
	            //on before show callback
	            opts.onBeforeShow && opts.onBeforeShow.call(that,opts);
	            //show dialog
	            that.target.removeClass("hidden");
	            that.isShow = true ;
	            VCM.dialog.queue.push(that);
	            //on show callback
	            opts.onShow && opts.onShow.call(that,opts);
	           	//bind event
				that.bindEvent();
			} else {
				//refresh old dialog
				that.target = $("#"+opts.id).html(opts.html);
				opts.onBeforeShow && opts.onBeforeShow.call(that,opts);
				opts.onShow && opts.onShow.call(that,opts);
				that.bindEvent();
			}
			VCM.debug("dialog queue",VCM.dialog.queue);
        },
        hide: function() {
        	var that = this,
				opts = this.opts,
				container = $(opts.container);
        	opts.onBeforeHide && opts.onBeforeHide.call(that,opts);
        	//hide dialog 
        	that.target.addClass("hidden").removeAttr("id");
            that.isShow = false ;
            VCM.dialog.remove(VCM.dialog.queue , opts.id);
        	// hide mask or not
            opts.mask && that.hideMask(container,opts);
            setTimeout(function() {
            	that.remove(that.target);
            }, 350);
            opts.onHide && opts.onHide.call(that,opts);
            VCM.debug("dialog queue",VCM.dialog.queue);
        },
        remove: function() {
        	var that = this;
        	that.target.remove();
        	VCM.dialog.maxZ = VCM.dialog.queue.length == 0 ? 100 : VCM.dialog.maxZ;
        	//queue show
        },
        bindEvent : function(){
        	var that = this,
				opts = this.opts,
				container = $(opts.container),
				eventType = VCM.os.desktop ? "click" : "touchend";
			if(opts.type == "alert"){
				that.target.find(".dialog_cancel").bind(eventType,function(e){
					that.hide();
				});				
			}
			if(opts.type == "confirm"){
				that.target.find(".dialog_done").bind(eventType,function(e){
					that.hide();
					opts.doneCallback.call(that,opts);
				});	
				that.target.find(".dialog_cancel").bind(eventType,function(e){
					that.hide();
					opts.cancelCallback.call(that,opts);
				});				
			}
			that.target.find(".dialog_close").bind(eventType,function(e){
				that.hide();
			});
			if(opts.timeOut){
				window.setTimeout(function(){
					that.hide();
				},opts.timeOut);
			}
			//
        },
        setPosition: function(container,target) {
        	var that = this;
        	if(VCM.os.desktop){
	        	target.css({
	        		"z-index" : VCM.dialog.maxZ++,
	        		"top" : (container[0].clientHeight / 2.1) - (target[0].clientHeight / 2) + that.opts.offset.top,
	        		"left" : (container[0].clientWidth / 2) - (target[0].clientWidth / 2) + that.opts.offset.left
	        	});
        	} else {
	        	target.css({
	        		"z-index" : VCM.dialog.maxZ++,
	        		"top" : ((window.innerHeight / 2.1) + window.pageYOffset) - (target[0].clientHeight / 2) + that.opts.offset.top,
	        		"left" : (window.innerWidth / 2) - (target[0].clientWidth / 2) + that.opts.offset.left
	        	});
        	}
        },
        showMask : function(container,opts){
        	var mask = "<div id=\""+ opts.id +"_mask\" class=\"dialog_mask ui_mask hidden\"></div>";
        	container.append(mask);
        	$("#"+ opts.id +"_mask").css({
        		"z-index" : VCM.dialog.maxZ++
        	}).removeClass("hidden");
        },
        hideMask : function(container,opts){
        	$("#"+ opts.id +"_mask").remove();
        }
    };
	VCM.dialog = $.dialog = function(opts) {
	    return new dialog(opts);
	};
	$.extend(VCM.dialog,{
		queue : [],
		maxZ : 100,
		close :function(id){
			//VCM.debug(this,id,this.indexOf(VCM.dialog.queue,id) ,this.queue);
			var i = this.indexOf(VCM.dialog.queue,id);
			if(i != -1){
				this.queue[i].hide();
			} else {
				return false;
			}
		},
		indexOf : function(queue,id){
		    for (var i = 0; i < queue.length; i++) {
		    	if(queue[i].opts.id == id) return i
		    }
		    return -1;
		},
		remove : function(queue,id){
			for (var i = 0; i < queue.length; i++) {
		       if(queue[i].opts.id == id) queue.splice(i, 1);
		    }
		}
		
	});
	
	/**
	 *@author Anderlu
	 *@param 
	 *@description initialization toast component
	 */	
	var tips = function(opts) {
		this.initialize(opts);
	};
    tips.prototype = {
    	opts : {},
    	isShow :false,
    	delayFun :null,
        initialize : function(opts){
        	this.opts = $.extend({
				id: VCM.uuid(), // tips id
		        message: null,//
		        onShow: null, //弹层显示后回调
		        onBeforeShow:null,//弹层显示前回调
		        onHide:null,//弹层关闭后回调
		        onBeforeHide:null,//弹层关闭前回调
		        timeOut: 2500,//延时自动关闭，单位毫秒
		        container: "#wrap",
		        isQueue:true,
		        offset:{
					left:0,
					top:0
				}
        	}, opts);
        	VCM.debug("tips initialize",this,this.opts,opts);
        	var that = this,
				opts = that.opts,
				container = $(opts.container),
				queue = VCM.tips.queue;
			if(!opts.isQueue && queue.length !=0){
				for(var i = 0 ; i < queue.length ; i++){
					$("#"+queue[i].opts.id).addClass("hidden");
				}
				this.show();
			} else if(opts.isQueue && queue.length !=0){
				VCM.tips.queue.push(that);
			} else {
        		this.show();
			}
		},
        show : function() {
			var that = this,
				opts = that.opts,
				container = $(opts.container),
				markup = "<div id=\""+ this.opts.id +"\" class=\"ui_tips hidden\">"+ this.opts.message +"</div>" ;
			// new tpis
            container.append(markup);
            that.target =  $("#"+opts.id);
            //set center position
            that.setPosition(container,that.target);
            //on before show callback
            opts.onBeforeShow && opts.onBeforeShow.call(that,opts);
            //show tpis
            that.target.removeClass("hidden");
            that.isShow = true;
           	VCM.tips.indexOf(VCM.tips.queue,opts.id) ==-1 && VCM.tips.queue.push(that);
            //on show callback
            opts.onShow && opts.onShow.call(that,opts);
            that.bindEvent();
        },
        hide: function() {
        	var that = this,
				opts = that.opts,
				container = $(opts.container);
        	opts.onBeforeHide && opts.onBeforeHide.call(that,opts);
        	//hide tpis 
        	that.target.addClass("hidden").removeAttr("id");
        	that.isShow = false;
        	VCM.tips.remove(VCM.tips.queue,opts.id);
            setTimeout(function() {
            	that.remove(that.target);
            }, 550);
            opts.onHide && opts.onHide.call(that,opts);
            // queue
        	if(opts.isQueue && VCM.tips.queue.length !=0){
				VCM.tips.queue[0].show();    		
        	}
        },
        remove: function() {
        	var that = this;
        	that.target.remove();
        	//queue show
        },
        setPosition: function(container,target){
        	var that = this;
        	if(VCM.os.desktop){
	        	target.css({
	        		"top" : (container[0].clientHeight / 1.2) - (target[0].clientHeight / 2) + that.opts.offset.top,
	        		"left" : (container[0].clientWidth / 2) - (target[0].clientWidth / 2) + that.opts.offset.left
	        	});
        	} else {
	        	target.css({
	        		"top" : ((window.innerHeight / 1.2) + window.pageYOffset) - (target[0].clientHeight / 2) + that.opts.offset.left,
	        		"left" : (window.innerWidth / 2) - (target[0].clientWidth / 2) + that.opts.offset.left
	        	});
        	}
        },   
        bindEvent : function(){
        	var that = this,
        		opts = this.opts,
        		container = $(opts.container),
				eventType = VCM.os.desktop ? "click" : "touchend";
			if(opts.timeOut){
				that.delayFun = window.setTimeout(function(){
					that.hide();
				},opts.timeOut);
			}
        }

    }
    VCM.tips = $.tips = function(opts) {
	    return new tips(opts);
	};
	$.extend(VCM.tips,{
		queue : [],
		indexOf : function(queue,id){
		    for (var i = 0; i < queue.length; i++) {
		    	if(queue[i].opts.id === id) return i
		    }
		    return -1;
		},
		remove : function(queue,id){
			for (var i = 0; i < queue.length; i++) {
		    	if(queue[i].opts.id === id) queue.splice(i, 1);
		    }
		}
	});
})();

VCM.debug("App start",this,VCM);
